# Copyright (c) 2010 Aldo Cortesi
# Copyright (c) 2010, 2014 dequis
# Copyright (c) 2012 Randall Ma
# Copyright (c) 2012-2014 Tycho Andersen
# Copyright (c) 2012 Craig Barnes
# Copyright (c) 2013 horsik
# Copyright (c) 2013 Tao Sauvage
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

import os
import subprocess
import logging


from libqtile import qtile
from libqtile import bar, layout, widget, hook
from libqtile.config import (
    Click,
    Drag,
    Group,
    Key,
    Match,
    Screen,
    KeyChord,
    ScratchPad,
    DropDown,
)
from libqtile.lazy import lazy
from libqtile.utils import guess_terminal


mod = "mod4"
# terminal = guess_terminal()
terminal = "kitty -e fish"
calendar = "kitty -e calcurse"
filemanager = "kitty -e ranger"
# player = "kitty -e cmus"
ncmpcpp = "kitty -e ncmpcpp"
password = "keepassxc"
cmus = "kitty -e cmus"


@lazy.function
def float_to_front(qtile):
    logging.info("bring floating windows to front")
    for group in qtile.groups:
        for window in group.windows:
            if window.floating:
                window.cmd_bring_to_front()


sticky_windows = []


@lazy.function
def toggle_sticky_windows(qtile, window=None):
    if window is None:
        window = qtile.current_screen.group.current_window
    if window in sticky_windows:
        sticky_windows.remove(window)
    else:
        sticky_windows.append(window)
    return window


@hook.subscribe.setgroup
def move_sticky_windows():
    for window in sticky_windows:
        window.togroup()
    return


@hook.subscribe.client_killed
def remove_sticky_windows(window):
    if window in sticky_windows:
        sticky_windows.remove(window)


# Below is an example how to make Firefox Picture-in-Picture windows automatically sticky.
# I have a German Firefox and don't know if the 'name' is 'Picture-in-Picture'.
# You can check yourself with `xprop` and then lookup at the line `wm_name`.
@hook.subscribe.client_managed
def auto_sticky_windows(window):
    info = window.info()
    if (
        info["wm_class"] == ["Toolkit", "firefox"]
        and info["name"] == "Picture-in-Picture"
    ):
        sticky_windows.append(window)


keys = [
    Key(["mod4", "shift"], "f", float_to_front),
    # A list of available commands that can be bound to keys can be found
    # at https://docs.qtile.org/en/latest/manual/config/lazy.html
    # Switch between windows
    Key([mod], "h", lazy.layout.left(), desc="Move focus to left"),
    Key([mod], "l", lazy.layout.right(), desc="Move focus to right"),
    # Key([mod], "j", lazy.layout.down(), desc="Move focus down"),
    Key(
        [mod],
        "j",
        lazy.group.next_window(),
        desc="Switch window focus to next window in group",
    ),
    Key([mod], "k", lazy.layout.up(), desc="Move focus up"),
    # Key([mod], "space", lazy.layout.next(), desc="Move window focus to other window"),
    # Move windows between left/right columns or move up/down in current stack.
    # Moving out of range in Columns layout will create new column.
    Key(
        [mod, "shift"], "h", lazy.layout.shuffle_left(), desc="Move window to the left"
    ),
    Key(
        [mod, "shift"],
        "l",
        lazy.layout.shuffle_right(),
        desc="Move window to the right",
    ),
    Key([mod, "shift"], "j", lazy.layout.shuffle_down(), desc="Move window down"),
    Key([mod, "shift"], "k", lazy.layout.shuffle_up(), desc="Move window up"),
    # Grow windows. If current window is on the edge of screen and direction
    # will be to screen edge - window would shrink.
    # Key([mod, "control"], "h", lazy.layout.grow_left(), desc="Grow window to the left"),
    # Key([mod, "control"], "l", lazy.layout.grow_right(), desc="Grow window to the right"),
    # Key([mod, "control"], "j", lazy.layout.grow_down(), desc="Grow window down"),
    # Key([mod, "control"], "k", lazy.layout.grow_up(), desc="Grow window up"),
    # Key([mod], "n", lazy.layout.normalize(), desc="Reset all window sizes"),
    # Monad Tile
    Key([mod, "shift"], "h", lazy.layout.swap_left()),
    Key([mod, "shift"], "l", lazy.layout.swap_right()),
    Key([mod, "shift"], "j", lazy.layout.shuffle_down()),
    Key([mod, "shift"], "k", lazy.layout.shuffle_up()),
    Key([mod], "i", lazy.layout.grow()),
    Key([mod], "m", lazy.layout.shrink()),
    Key([mod], "n", lazy.layout.normalize()),
    Key([mod], "o", lazy.layout.maximize()),
    Key([mod, "shift"], "space", lazy.layout.flip()),
    # Toggle between split and unsplit sides of stack.
    # Split = all windows displayed
    # Unsplit = 1 window displayed, like Max layout, but still with
    # multiple stack panes
    # Key(
    #     [mod, "shift"],
    #     "Return",
    #     lazy.layout.toggle_split(),
    #     desc="Toggle between split and unsplit sides of stack",
    # ),
    Key([mod, "shift"], "Return", lazy.spawn(terminal), desc="Launch terminal"),
    # Toggle between different layouts as defined below
    Key([mod, "shift"], "Tab", lazy.next_layout(), desc="Toggle between layouts"),
    Key(
        [mod], "Tab", lazy.screen.toggle_group(), desc="Move to the last visited group"
    ),
    Key([mod, "shift"], "c", lazy.window.kill(), desc="Kill focused window"),
    Key([mod, "control"], "r", lazy.reload_config(), desc="Reload the config"),
    Key([mod, "shift"], "q", lazy.shutdown(), desc="Shutdown Qtile"),
    # Key([mod], "r", lazy.spawncmd(), desc="Spawn a command using a prompt widget"),
    Key([mod], "p", lazy.spawn("dmenu_run -p 'RUN:'")),
    # Key([mod], "r", lazy.spawn("rofi -show run"), desc="launch rofi run"),
    # Key([mod], "u", lazy.spawn("kitty -e ranger")),
    # Key([mod], "c", lazy.spawn("kitty -e calcurse")),
    Key(["mod1"], "l", lazy.spawn("slock")),
    Key([mod], "Print", lazy.spawn("flameshot gui")),
    Key(["mod1"], "n", lazy.spawn("nemo"), desc="Nemo File Manager"),
    Key(["mod1"], "z", lazy.spawn("zuluCrypt-gui")),
    Key([mod], "f", lazy.window.toggle_fullscreen()),
    Key([mod], "b", lazy.hide_show_bar(position="top")),
    Key([mod], "F12", lazy.spawn("firefox")),
    Key([mod, "shift"], "F12", lazy.spawn("firefox -private-window")),
    KeyChord(
        ["control"],
        "m",
        [
            Key([], "e", lazy.spawn("element-desktop")),
            Key([], "t", lazy.spawn("telegram-desktop")),
        ],
    ),
    # Change the volume if your keyboard has special volume keys.
    # Sound
    Key([], "XF86AudioMute", lazy.spawn("amixer -q set Master toggle")),
    Key([], "XF86AudioLowerVolume", lazy.spawn("amixer -c 0 sset Master 5- unmute")),
    Key([], "XF86AudioRaiseVolume", lazy.spawn("amixer -c 0 sset Master 5+ unmute")),
    # Volume control
    # Key([], "XF86AudioLowerVolume", lazy.spawn("pamixer --decrease 5")),
    # Key([], "XF86AudioRaiseVolume", lazy.spawn("pamixer --increase 5")),
    # Key([], "XF86AudioMute", lazy.spawn("pamixer --toggle-mute")),
    # Brightness Control
    Key([], "XF86MonBrightnessUp", lazy.spawn("brightnessctl set +10%")),
    Key([], "XF86MonBrightnessDown", lazy.spawn("brightnessctl set 10%-")),
    Key(
        [mod],
        "s",
        toggle_sticky_windows(),
        desc="Toggle state of sticky for current window",
    ),
]

groups = [
    Group("1", label="1", layout="max"),
    Group("2", label="2", matches=[Match(wm_class=["firefox"])], layout="max"),
    Group(
        "3",
        label="3",
        matches=[Match(wm_class=["jetbrains-pycharm-ce", "code-oss"])],
        layout="max",
    ),
    Group("3", label="3", matches=[Match(wm_class=["obsidian"])], layout="max"),
    Group(
        "4",
        label="4",
        matches=[Match(wm_class=["element", "telegram-desktop", "rocket.chat"])],
        layout="max",
    ),
    Group("5", label="5", layout="max"),
    Group("6", label="6", layout="max"),
    Group("7", label="7", matches=[Match(wm_class=["virt-manager"])], layout="max"),
    Group("8", label="8", layout="max"),
    Group("9", label="9", matches=[Match(wm_class=["qbittorrent"])], layout="max"),
]

# groups = [Group(i) for i in "123456789"]

for i in groups:
    keys.extend(
        [
            # mod1 + letter of group = switch to group
            Key(
                [mod],
                i.name,
                lazy.group[i.name].toscreen(),
                desc="Switch to group {}".format(i.name),
            ),
            # mod1 + shift + letter of group = switch to & move focused window to group
            Key(
                [mod, "shift"],
                i.name,
                lazy.window.togroup(i.name, switch_group=True),
                desc="Switch to & move focused window to group {}".format(i.name),
            ),
            # Or, use below if you prefer not to switch to that group.
            # # mod1 + shift + letter of group = move focused window to group
            # Key([mod, "shift"], i.name, lazy.window.togroup(i.name),
            #     desc="move focused window to group {}".format(i.name)),
        ]
    )

# SCRATCHPADS
groups.append(
    ScratchPad(
        "scratchpad",
        [
            DropDown("1", terminal, x=0.10, y=0.0, width=0.8, height=0.8),
            DropDown("2", filemanager, x=0.10, y=0.0, width=0.8, height=0.8),
            DropDown("3", calendar, x=0.10, y=0.0, width=0.8, height=0.8),
            # DropDown("4", player, x=0.10, y=0.0, width=0.8, height=0.8),
            DropDown("5", ncmpcpp, x=0.10, y=0.0, width=0.8, height=0.8),
            DropDown("6", password, x=0.10, y=0.10, width=0.8, height=0.8),
            DropDown("7", "galculator", x=0.40, y=0.30, width=0.2, height=0.3),
            DropDown("8", cmus, x=0.10, y=0.0, width=0.8, height=0.8),
        ],
    )
)

keys.extend(
    [
        Key(["mod1"], "grave", lazy.group["scratchpad"].dropdown_toggle("1")),
        Key(["mod1"], "r", lazy.group["scratchpad"].dropdown_toggle("2")),
        Key(["mod1"], "c", lazy.group["scratchpad"].dropdown_toggle("3")),
        # Key(["mod1"], "m", lazy.group["scratchpad"].dropdown_toggle("4")),
        Key(["mod1"], "m", lazy.group["scratchpad"].dropdown_toggle("5")),
        Key(["mod1"], "p", lazy.group["scratchpad"].dropdown_toggle("6")),
        Key(["mod1"], "q", lazy.group["scratchpad"].dropdown_toggle("7")),
        Key(["mod1", "control"], "m", lazy.group["scratchpad"].dropdown_toggle("8")),
    ]
)

layouts = [
    layout.Max(),
    layout.MonadTall(
        border_normal="#373b41",
        # border_focus=["#b294bb"],
        border_focus=["#1177aa"],
        border_width=2,
        ratio=0.7,
        new_client_position="before_current",
        margin=4,
    ),
    layout.MonadWide(
        border_normal="#373b41",
        # border_focus=["#b294bb"],
        border_focus=["#1177aa"],
        border_width=2,
        ratio=0.7,
        new_client_position="before_current",
        margin=4,
    ),
    # layout.Floating(),
    # layout.MonadThreeCol(
    #     border_normal="#373b41",
    #     # border_focus=["#b294bb"],
    #     border_focus=["#1177aa"],
    #     border_width=2,
    #     ratio=0.7,
    #     new_client_position="before_current",
    #     margin=4,
    # ),
    # layout.TreeTab(
    #     active_bg="#b294bb",
    #     active_fg="#373b41",
    #     bg_color="#1d1f21",
    #     border_width=4,
    #     inactive_bg="#282a2e",
    #     inactive_fg="#c5c8c6",
    #     level_shift=8,
    #     panel_width=150,
    #     padding_x=8,
    #     padding_y=4,
    #     margin_y=0,
    #     margin_left=0,
    #     place_right=False,
    #     section_bottom=16,
    #     section_left=9,
    #     sections=["Root", "Second"],
    # ),
    #
    # layout.Columns(
    #     border_normal_stack=["#85678f"],
    #     border_width=4,
    #     fair=True,
    # ),
    # Try more layouts by unleashing below layouts.
    # layout.Stack(num_stacks=2),
    # layout.Bsp(),
    # layout.Matrix(),
    # layout.RatioTile(),
    # layout.Tile(),
    # layout.VerticalTile(),
    # layout.Zoomy(),
]

widget_defaults = dict(
    font="JetBrains Mono",
    # font="Iosevka Term Light",
    fontsize=12,
    padding=4,
)
extension_defaults = widget_defaults.copy()

screens = [
    Screen(
        top=bar.Bar(
            [
                # widget.Sep(
                #     padding=10,
                #     linewidth=0,
                # ),
                widget.WidgetBox(
                    close_button_location="left",
                    # text_open="  󰔰  ",
                    text_open="   ",
                    text_closed="     ",
                    # text_open="  󰔰  ",
                    # text_closed=" 󰧀  ",
                    # background="#5f819d",
                    # foreground="#1d1f21",
                    foreground="#f2f2f2",
                    fontsize=12,
                    widgets=[
                        widget.Sep(
                            padding=10,
                            linewidth=1,
                        ),
                        widget.TextBox(
                            text="   Reboot ",
                            mouse_callbacks={
                                "Button1": lambda: qtile.cmd_spawn("kitty -e reboot"),
                            },
                        ),
                        widget.Sep(
                            padding=10,
                            linewidth=1,
                        ),
                        widget.TextBox(
                            text="   PowerOff ",
                            mouse_callbacks={
                                "Button1": lambda: qtile.cmd_spawn(
                                    "kitty -e shutdown -h now"
                                ),
                                # "Button1": lambda: qtile.cmd_spawn("kitty -e poweroff"),
                            },
                        ),
                        widget.Sep(
                            padding=10,
                            linewidth=1,
                        ),
                        widget.QuickExit(default_text="Quit QTILE"),
                        widget.Sep(
                            padding=10,
                            linewidth=1,
                        ),
                    ],
                ),
                # widget.Sep(
                #     padding=10,
                #     linewidth=0,
                # ),
                # widget.GroupBox(
                #     background="#282a2e",
                #     active="#f1f1f1",
                #     highlight_color="#1d1f21",
                #     this_current_screen_border="#8c9440",
                #     block_highlight_text_color="#8c9440",
                #     inactive="#707880",
                #     highlight_method="line",
                #     borderwidth=2,
                #     padding_x=8,
                #     rounded=False,
                #     hide_unused=False,
                #     fontsize=12,
                # ),
                widget.GroupBox(
                    # background="#282a2e",
                    background="#10181f",
                    active="#f1f1f1",
                    highlight_color="#1d1f21",
                    # this_current_screen_border="#5f819d",
                    this_current_screen_border="#1177aa",
                    # block_highlight_text_color="#1d1f21",
                    block_highlight_text_color="#f2f2f2",
                    inactive="#707880",
                    highlight_method="block",
                    borderwidth=2,
                    padding_x=8,
                    rounded=False,
                    hide_unused=False,
                    fontsize=14,
                ),
                widget.CurrentLayoutIcon(
                    scale=0.6,
                ),
                widget.Sep(
                    padding=10,
                    linewidth=0,
                ),
                widget.Prompt(),
                widget.WindowName(
                    fontsize=14,
                ),
                widget.WidgetBox(
                    close_button_location="right",
                    text_open="  󰔰  ",
                    text_closed="  󰧀  ",
                    # background="#5f819d",
                    background="#1177aa",
                    foreground="#f2f2f2",
                    # foreground="#1d1f21",
                    fontsize=14,
                    widgets=[
                        widget.Wttr(
                            location={"Simferopol": "󰖚"},
                            fontsize=14,
                            format="2",
                            background="#282a2e",
                            padding=10,
                        ),
                        widget.Sep(
                            padding=10,
                            linewidth=1,
                            background="#282a2e",
                        ),
                        widget.CryptoTicker(
                            update_interval=600,
                            fontsize=14,
                            background="#282a2e",
                            padding=10,
                        ),
                    ],
                ),
                widget.Cmus(
                    play_color="#8c9440",
                    noplay_color="#CC6666",
                    update_interval=0.5,
                    markup=True,
                    background="#282a2e",
                    padding=10,
                    margin=10,
                    fontsize=14,
                ),
                # widget.Sep(
                #     padding=10,
                #     linewidth=1,
                # ),
                widget.CheckUpdates(
                    distro="Arch_checkupdates",
                    fmt="    {}",
                    fontsize=14,
                    update_interval=300,
                    no_update_string="No",
                    mouse_callbacks={
                        # 'Button1': lambda: qtile.cmd_spawn("kitty -e sudo pacman -Syyu"),
                        "Button1": lambda: qtile.cmd_spawn(
                            "kitty -e sudo pacman -Syyu"
                        ),
                        "Button2": lambda: qtile.cmd_spawn("kitty -e yay -Sc"),
                        "Button3": lambda: qtile.cmd_spawn("kitty -e sudo pacman -Sc"),
                    },
                ),
                widget.Sep(
                    padding=10,
                    linewidth=1,
                ),
                # widget.Net(
                #     fmt=' {}',
                #     fontsize=12,
                #     interface='enp0s31f6',
                #     format='{interface}: U {up} D {down} T {total}',
                #     prefix='M',
                # ),
                # widget.Sep(
                #     padding=10,
                #     linewidth=1,
                # ),
                # widget.Memory(
                #     fmt=' {}',
                #     fontsize=12,
                #     mouse_callbacks={
                #         'Button1': lambda: qtile.cmd_spawn('st -e htop'),
                #         'Button3': lambda: qtile.cmd_spawn('st -e btm'),
                #     },
                # ),
                # widget.Sep(
                #     padding=10,
                #     linewidth=1,
                # ),
                widget.DF(
                    fmt=" {}",
                    partition="/",
                    measure="G",
                    format="{p} ({uf}{m}|{r:.0f}%)",
                    update_interval=60,
                    fontsize=14,
                    visible_on_warn=False,
                    warn_space=40,
                    mouse_callbacks={
                        "Button1": lambda: qtile.cmd_spawn("kitty -e ncdu"),
                    },
                ),
                widget.Sep(
                    padding=10,
                    linewidth=1,
                ),
                widget.ThermalZone(
                    fmt=" {}",
                    fontsize=14,
                    mouse_callbacks={
                        "Button3": lambda: qtile.cmd_spawn("kitty -e btm"),
                    },
                ),
                widget.Sep(
                    padding=10,
                    linewidth=1,
                ),
                widget.Battery(
                    fmt="󰁹 {}",
                    fontsize=14,
                    update_interval=60,
                    battery=0,
                    format="{char} {percent:2.0%} {hour:d}:{min:02d}",
                    # format = '{char} {percent:2.0%} {hour:d}:{min:02d} {watt:.2f} W',
                ),
                # NB Systray is incompatible with Wayland, consider using StatusNotifier instead
                # widget.StatusNotifier(),
                widget.Sep(
                    padding=10,
                    linewidth=1,
                ),
                widget.Clock(
                    fmt="󱇻 {}",
                    format="%a, %b %d %T",
                    fontsize=14,
                    mouse_callbacks={
                        "Button3": lambda: qtile.cmd_spawn("kitty -e calcurse")
                    },
                ),
                widget.Sep(
                    padding=10,
                    linewidth=1,
                ),
                # widget.PulseVolume(
                #     fmt="󰕾 {}",
                #     fontsize=14,
                #     emoji=False,
                #     limit_max_volume=True,
                #     mouse_callbacks={
                #         'Button3': lambda: qtile.cmd_spawn("kitty -e alsamixer")
                #     },
                # ),
                # widget.Volume(
                #     fmt="󰕾 {}",
                #     fontsize=14,
                #     emoji=False,
                #     limit_max_volume=True,
                #     mouse_callbacks={
                #         "Button3": lambda: qtile.cmd_spawn("kitty -e alsamixer")
                #     },
                # ),
                widget.TextBox(
                    fmt="󱡫",
                    mouse_callbacks={
                        "Button1": lambda: qtile.cmd_spawn("kitty -e alsamixer")
                    },
                ),
                widget.Sep(
                    padding=10,
                    linewidth=1,
                ),
                widget.Systray(),
                widget.Sep(
                    padding=10,
                    linewidth=0,
                ),
            ],
            24,
            # border_width=[2, 0, 2, 0],  # Draw top and bottom borders
            # border_color=["ff00ff", "000000", "ff00ff", "000000"]  # Borders are magenta
            # background="#1d1f21"
            background="#10181f",
        ),
    ),
]

# Drag floating layouts.
mouse = [
    Drag(
        [mod],
        "Button1",
        lazy.window.set_position_floating(),
        start=lazy.window.get_position(),
    ),
    Drag(
        [mod], "Button3", lazy.window.set_size_floating(), start=lazy.window.get_size()
    ),
    Click([mod], "Button2", lazy.window.bring_to_front()),
]

dgroups_key_binder = None
dgroups_app_rules = []  # type: list
follow_mouse_focus = True
bring_front_click = False
cursor_warp = False
floating_layout = layout.Floating(
    border_normal="#373b41",
    # border_focus="#b294bb",
    border_focus=["#1177aa"],
    border_width=2,
    float_rules=[
        # Run the utility of `xprop` to see the wm class and name of an X client.
        *layout.Floating.default_float_rules,
        Match(wm_class="confirmreset"),  # gitk
        Match(wm_class="makebranch"),  # gitk
        Match(wm_class="maketag"),  # gitk
        Match(wm_class="ssh-askpass"),  # ssh-askpass
        Match(title="branchdialog"),  # gitk
        Match(title="pinentry"),  # GPG key password entry
        Match(title="galculator"),  # Galculator
        # Match(title="KeePassXC"),  # KeePassXC pass manager
    ],
)
auto_fullscreen = True
focus_on_window_activation = "smart"
reconfigure_screens = True

# If things like steam games want to auto-minimize themselves when losing
# focus, should we respect this or not?
auto_minimize = True

# When using the Wayland backend, this can be used to configure input devices.
wl_input_rules = None

# XXX: Gasp! We're lying here. In fact, nobody really uses or cares about this
# string besides java UI toolkits; you can see several discussions on the
# mailing lists, GitHub issues, and other WM documentation that suggest setting
# this string if your java app doesn't work correctly. We may as well just lie
# and say that we're a working one by default.
#
# We choose LG3D to maximize irony: it is a 3D non-reparenting WM written in
# java that happens to be on java's whitelist.
wmname = "LG3D"
